package com.meme.util;

import java.io.File;
import java.io.IOException;
import java.util.Stack;

import org.apache.log4j.Logger;

import com.meme.io.editor.Sprite2dXmlFileLoader;

public class FileUtil 
{
	static Logger logger = Logger.getLogger (FileUtil.class);
	
	public static File getFile (String filename)
	{
		return new File ( getCanonicalPathFileName(filename) );
	}
	
    public static void deleteFile ( String filename ) //throws IOException
    {
        File file = new File ( filename );
        file.delete();
    }
    
    public static String getCanonicalPathFileName ( String filename ) //throws IOException
    {
    	try
    	{
    		return new File ( filename ).getCanonicalPath();
    	}
    	catch (Exception e)
    	{
    		logger.error ("Error in getCanonicalPathFileName: filename=" + filename);
    		
    		return null;
    	}
    }

    public static String getCurrentDir ()  throws IOException
    {
        return new File ( "" ).getCanonicalPath();
    }

    public static String getFileDir ( String filename )
    {
        return new File ( filename ).getParent();
    }
	
    public static String getFullPathFilename (String filename, String relativeTo) 
    	//throws Exception
	{
    	//filename = getCanonicalPathFileName (filename);
    	
    	if ( new File ( filename ).isAbsolute() )
    		return filename;
    	
    	relativeTo = getCanonicalPathFileName (relativeTo);

    	if ( ! new File ( relativeTo ).isAbsolute() )
	    {
	        logger.error ( "relativeTo must be absolute." );
	        return null;
	    }
	
	    try
	    {
		    if (  new File ( relativeTo ).isFile() )
		        return new File ( getFileDir( relativeTo ), filename ).getCanonicalPath();
		    else // if (  new File ( relativeTo ).isDirectory() )
		    {
		        return new File ( relativeTo, filename ).getCanonicalPath();
		    }
	    } catch (Exception e)
	    {
	    	logger.error(e);
	        logger.error ( "Error in getFullPathFilename. filename=" + filename + ", relativeTo=" + relativeTo );
	        return null;
	    }
	}

	public static String getRelativePathFilename ( String filename, String relativeTo )
	    //throws Exception
	{
		filename = getCanonicalPathFileName (filename);
		relativeTo = getCanonicalPathFileName (relativeTo);
		
	    filename = getFullPathFilename ( filename, relativeTo );

	
	    //if ( ! new File ( relativeTo ).isFile() )
	    if ( new File ( relativeTo ).isDirectory() )
	        relativeTo = relativeTo + File.separatorChar;
	
	    if ( ! new File ( filename ).isFile() )
	        filename = filename + File.separatorChar;
	
	    int prev_slash_pos = 0;
	    int curr_slash_pos;
	    do
	    {
	        curr_slash_pos = relativeTo.indexOf(File.separatorChar, prev_slash_pos + 1);
	        if ( curr_slash_pos > 0
	             &&
	             relativeTo.regionMatches( true, prev_slash_pos,
	                                       filename, prev_slash_pos,
	                                       curr_slash_pos + 1 - prev_slash_pos ) )
	        {
	            prev_slash_pos = curr_slash_pos;
	        }
	        else break;
	    } while ( true );
	
	    int common_path_length = prev_slash_pos;
	    int gen_gaps = 0;
	    do
	    {
	        curr_slash_pos = relativeTo.indexOf(File.separatorChar, prev_slash_pos + 1);
	        if ( curr_slash_pos > 0 )
	        {
	            ++ gen_gaps;
	            prev_slash_pos = curr_slash_pos;
	        }
	        else break;
	    } while ( true );
	
	
	
	    StringBuffer rel_path = new StringBuffer(255);
	
	    if ( gen_gaps == 0 && common_path_length == filename.length() )
	    {
	        rel_path.append('.');
	        rel_path.append(File.separatorChar);
	    }
	    else
	    {
	        while ( -- gen_gaps >= 0 )
	        {
	            rel_path.append('.');
	            rel_path.append('.');
	            rel_path.append(File.separatorChar);
	        }
	
	        rel_path.append ( filename.substring( common_path_length + 1 ) );
	    }
	
	    return rel_path.toString();
	}

	public static String getRelativePathFilename ( String filename )
	    throws Exception
	{
	    return getRelativePathFilename ( filename, getCurrentdir() );
	}

	public static String getFilename (String pathFilename)
	{
		pathFilename = getCanonicalPathFileName (pathFilename);
        int slash_pos = pathFilename.lastIndexOf(File.separatorChar);
        return pathFilename.substring(slash_pos + 1);
	}
	
    public static String getFilenameWithoutExt(String filename)
    {
    	filename = getCanonicalPathFileName (filename);
       int slash_pos = filename.lastIndexOf(File.separatorChar);
       //if ( slash_pos < 0 ) slash_pos = 0;
       ++ slash_pos;
       int dot_pos = filename.lastIndexOf(".");
       if ( dot_pos > slash_pos )
          return filename.substring( slash_pos, dot_pos );
       else
    	   return filename.substring( slash_pos );
    }

    public static String getFilenameExt(String filename)
    {
    	filename = getCanonicalPathFileName (filename);
    	
//       int slash_pos = filename.lastIndexOf(File.separatorChar);
//       //if ( slash_pos < 0 ) slash_pos = 0;
//       ++ slash_pos;
//       int dot_pos = filename.indexOf(".", slash_pos );
//       if ( dot_pos > slash_pos )
//          return filename.substring( dot_pos + 1 );
//       else
//          return "";
       
       int dot_pos = filename.lastIndexOf(".");
       if (dot_pos < 0)
    	   return "";
       int slash_pos = filename.indexOf(File.separatorChar, dot_pos);
       if (slash_pos < 0)
    	   return filename.substring( dot_pos + 1 );
       else
    	   return "";
    }
    

	static Stack<String> _currentDirStack = new Stack<String> ();
	
	public static void pushCurrentDir( String dir )
	{
	    _currentDirStack.push( dir );
	}
	
	public static String getCurrentdir()
	{
	    return _currentDirStack.peek();
	}
	
	public static String popCurrentDir()
	{
	    return  _currentDirStack.pop();
	}
	
	public static void clearCurrentDirStack ()
	{
		_currentDirStack.clear();
	}

	
}
